Глава 20
ГЛОБАЛЬНЫЕ ОБЪЕКТЫ И НАСТРОЙКА ПРОГРАММ
С любой запущенной программой автоматически связываются четыре глобальных объекта: Application (программа), screen (экран), Printer (принтер) и Clipboard (буфер межпрограммного обмена). В этой главе рассматриваются свойства и методы этих объектов. Отдельный раздел посвящен индивидуальной настройке программ.
20.1. APPLICATION
Объект Application относится к классу TAppiication и инкапсулирует важнейшие свойства и методы программы как таковой. Он создается автоматически и доступен любой программе. Объект не помещен в палитру компонентов, поэтому его свойства недоступны на этапе конструирования, но становятся доступны при прогоне программы[ Некоторые свойства программы (в том числе ее пиктограмма, сведения о версии и используемом языке) могут устанавливаться с помощью менеджера проекта (опция project | Options и страница Application).].
Application является посредником между программой и операционной системой. В частности, с его помощью осуществляется диспетчеризация сообщений Windows, реализуется контекстно-чувствительная справочная служба, он обрабатывает клавиши-акселераторы, исключительные ситуации и т. д.
Ниже описываются некоторые свойства Application для приложения Windows (для приложения Linux объект Application несколько отличается). Опущенные свойства предназначены в основном для прямого обращения к API-функциям Windows.
property Active: Boolean; |
Содержит True, если любое окно программы имеет фокус ввода |
property BiDiMode: TBiDiMode; |
Определяет свойство bidiMode (см. п. 17.12) для программы в целом |
property CurrentHelpFile: Strings; |
Определяет имя текущего справочного файла |
property ExeName: Strings; |
Содержит полное имя (с маршрутом доступа) исполняемого файла программы |
property HelpFile: String; |
Определяет имя файла справочной службы |
property Hint: String; |
Содержит длинную часть оперативной подсказки |
property HintColor: TColor;
|
Определяет цвет фона ярлычка оперативной подсказки |
property HintHidePause: Integers;
|
Определяет паузу (в миллисекундах) от момента появления ярлычка до его исчезновения |
property HintPause: Integer;
|
Определяет паузу (в миллисекундах) от момента остановки указателя мыши до появления ярлычка |
property HintShortPause: Integers; |
Определяет паузу (в миллисекундах) появления ярлычка при переходе с одного компонента на другой |
property Icon: TIcon; |
Определяет пиктограмму программы |
property MainForm: TForm; |
Определяет главное окно программы |
property ShowHint: Boolean; |
Разрешает/запрещает показ ярлычков для всех окон программы |
property ShowMainForm: Boolean;
|
Разрешает/запрещает показ главного окна в момент старта программы |
property Terminated: Boolean; |
Содержит True, если программа должна прекратить работу. Используется в приложениях с интенсивным счетом для контроля необходимости прекращения дальнейшей работы |
property Title: String; |
Определяет текст под пиктограммой минимизированной программы |
property UpdateFormatSettings: Boolean;
|
Если содержит True, программа автоматически будет учитывать новые форматные установки Windows (например, новый разделитель целой и дробной частей числа) при их изменении в момент работы программы. |
property UpdateMetricSet;Boolean; |
Если содержит True, программа автоматически будет учитывать новые метрические установки Windows (например, новый системный шрифт) при их изменении в момент работы программы |
Методы Application:
procedure BringToFront; |
Помещает окно, которое было активным в последний раз, поверх остальных окон |
procedure HandleException(Sender: TObject) ; |
Осуществляет умалчиваемую обработку исключительных ситуаций. Используется при разработке новых компонентов |
function HelpCommand(Command: Word; Data: Longint): Boolean; |
Посылает справочной службе команду Command и параметр Data |
procedure HandleMessage; |
Приостанавливает работу программы до тех пор, пока не будут обработаны все сообщения, после чего создает событие Onidle |
procedure CreateForm(FormClass: TFormClass; var Reference) ; |
Создает объект-окно: вызывает конструктор класса TFormClass и связывает его значение с переменной Reference |
procedure CancelHint; |
Запрещает показ ярлычков оперативной подсказки |
function HelpContext(Context: THelpContext): Boolean; |
Вызывает раздел context справочной службы и возвращает True, если такой раздел существует |
function HelpJump(const JumpID: String): Boolean; |
Вызывает раздел справочной службы по его имени JumpID и возвращает True, если такой раздел существует |
procedure Hide Hint; |
Убирает текущий ярлычок оперативной подсказки |
TWindowHook = function(var Mes sage: TMessage): Boolean of object procedure HookMainWindow(Hook: TWindowHook); |
Регистрирует функцию для перехвата сообщений Windows |
function MessageBox(Text, Cap tion: PChar; Flags: Longint): Integer; |
Создает и показывает диалоговое окно с текстом и кнопками: Text - сообщение в окне; Caption - заголовок окна. Назначение Flags и возвращаемое значение см. ниже |
procedure Minimize; |
Минимизирует программу до пиктограммы |
procedure NormalizeTopMosts; |
Приостанавливает действие стиля fsTopMost для всех окон программы |
procedure NormalizeAllTopMosts;
|
Распространяет действие NormalizeTop Mosts на главное окно программы |
procedure ProcessMessages;
|
То же, что HandleMessage, но не создает событие OnIdle |
procedure Restore;
|
Восстанавливает первоначальные размеры всех окон программы до ее минимизации |
procedure RestoreTopMosts;
|
Восстанавливает действие стиля fsTopMost для всех окон программы |
procedure Run; |
Запускает цикл получения и обработки Windows-сообщений |
procedure ShowException(EiException) ; |
Реализует умалчиваемую обработку исключительных ситуаций |
procedure Terminate; |
Завершает работу программы |
procedure UnhookMainWindow(Hook:TWindowHook); |
Удаляет перехватчик сообщений, ранее установленный методом ookMainWindow. Параметр Hook - имя той же функции перехвата, что и при обращении к HookMainWindow |
С помощью методов HandleException и ProcessMessages программа может временно приостановить свою работу до тех пор, пока не будут обработаны все предназначенные ей сообщения Windows. Это бывает необходимо для обновления видимых компонентов в процессе отображения длительного по времени цикла работы. Если, например, программа изменит текст метки или состояние компонента progressBar, сообщение об этом поступит в очередь сообщений и останется в ней, пока не закончится текущая работа. Вызов HandleException или ProcessMessages в этом случае позволит метке или ProgressBar действительно обновить свой вид и отобразить новую фазу процесса. Разница между методами HandieException И ProcessMessages состоит в том, что первый после очистки очереди сообщений вызывает обработчик фонового события OnIdie, а второй не делает этого. Назначение события onidie см. после описания событий объекта Application.
С помощью метода HookMainWindow можно зарегистрировать функцию Hook, которая будет получать все адресованные программе сообщения windows. По моим наблюдениям, эта функция получает
Сообщение Message параллельно c главной оконной функцией Application. ProcessMessage или после нее, т. к. ни изменение сообщения, ни возвращаемый функцией Hook результат никак не влияют на поведение программы. Как следует из встроенной справочной службы, в качестве функции Hook должна регистрироваться оконная функция диалогового окна, созданного не с помощью Delphi. Если вы решите использовать HookMainWindow для наблюдения за посылаемыми программе сообщениями, не забудьте перед завершением программы отключить регистрацию Hook методом unHookMainwin-dow, в противном случае завершение работы программы будет сопровождаться сообщением об ошибке. Для целей перехвата сообщений и их возможного изменения следует использовать обработчик Application. OnMessage, который вызывается из оконной функции Программы Application. ProcessMessage до вызова методов Trans-lateMessage И DispatchMessage, реализующих стандартную обработку сообщений. В Delphi 5 (и 6) появилось дополнительное удобное средство перехвата сообщений - компонент TApplicationEvents (см. п. 18.2.14).
Функция MessageBox дает удобное средство вывода на экран небольшого -сообщения. Параметр Flags может быть произвольной комбинацией следующих значений:
mbA bort Retry Ignore |
В окно вставляются кнопки Abort, Retry, Ignore |
mbApplModal |
Пользователь должен закрыть это окно перед тем, как продолжить работу с окном, его породившим; однако он может переходить в другие окна и работать с ними. Этот признак берется по умолчанию, если не определены ни mbSystemModal, ни inbTaskModal |
mbDefButtonl |
Кнопкой по умолчанию является кнопка 1 |
mbDefButton2 |
Кнопкой по умолчанию является кнопка 2 |
mbDefButton3 |
Кнопкой по умолчанию является кнопка 3 |
mbDefButton4 |
Кнопкой по умолчанию является кнопка 4 |
mbHelp |
Вставляется кнопка Help |
mbIconAftensk |
В окно вставляется пиктограмма в виде строчной буквы i в кружке |
mblconExclcimation |
В окно вставляется пиктограмма в виде знака восклицания |
mbIconHand |
В окно вставляется пиктограмма в виде знака |
mblconlnformation |
Стоп То же,что и mbIconAsterisk |
mb IconQuestion |
В окно вставляется пиктограмма в виде знака вопроса |
mbIconStop |
To же, ЧТО И mbIconHand |
mb0k |
В окно вставляется кнопка Ok |
mbOkCancel |
В окно вставляются кнопки Ok и Cancel |
mbRetry Cancel |
В окно вставляются кнопки Retry и Cancel |
mbSy stem Modal |
Все программы приостанавливают свою работу, пока пользователь не закроет это окно |
mbTaskModal |
Приостанавливается работа во всех окнах данной программы до тех пор, пока пользователь не закроет это окно |
mbYesNo mb Yes No Cancel |
В окно вставляются кнопки Yes, ыо В окно вставляются кнопки Yes, No, Cancel |
Например:
Application.MessageBox('Текст в окне', 'Заголовок окна', mb_IconQuestion+mb_YesNo) ;
Функция MessageBox возвращает такие значения:
idAbort idCancel idlgnore idOk |
Была нажата кнопка Abort Была нажата кнопка cancel Была нажата кнопка ignore Была нажата кнопка ok |
idNo idRetry idYes |
Была нажата кнопка No Была нажата кнопка Retry Была нажата кнопка Yes |
Альтернативой MessageBox является глобальная функция MessageDIg, объявленная в модуле Dialogs:
function MessageDIg(const.Msg: String;AType: TMsgDIgType; AButtons: TMsgDIgButtons;HelpCtx:- Longint): Word;
Эта? функция имеет шараметр; HelpCtx, с помощью которого создаваемое ею окно можно легко связать с Help-службой. В отличие от MessageBox заголовок окна MessageDIg не может изменяться программистом - он опредёляётся типом окна, задаваемым параметром AType (возможные значения: mtWarning - пиктограмма в виде знака: Восклицания, заголовок Warning; mtError - пиктограмма в виде знака Стоп заголовок Error; mtlnformation:-- пиктограмма в виде:
Буквы i, заголовок information; mtConfirmation - пиктограмма в виде знака вопроса, заголовок Confirm; mtCustom - нет пиктограммы, заголовок содержит имя исполняемого файла программы) Набор кнопок задаётся в виде конструктора множества и может включать: mbYes-—кнопка Хез (результат, возвращаемый функцией при нажатии на эту кнопку - nu-Yes); mbNo -кнопка. No (mrNo); mbOk - кнопка OK (mrOk); mbCancel - кнопка ; Cancel (mrCancel);
mbHelp -кнопка Help (после нажатия на эту кнопку окно не закрывается); mbAbort - кнопка Abort (mrAbort); mbIgnore- кнопка Ignore (mrlgnore); mbAll —кнопка All .(mbА11). В отличие от MessageBox раскрытие окна MessageDIg не сопровождается системным звуком.
Для объекта Application определены следующие события:
property OnActivate: TNotifyEvent; |
Возникает, когда программа получает фокус ввода |
property OnDeactivate: TNotifyEvent; |
Возникает, когда программа теряет фокус ввода |
TExceptionEvent = procedure (Sender: TObject; E: Exception) of object; property OnException: TException Event; |
Обработчик этого события реализует умалчиваемую обработку исключительных ситуаций
|
THelpEvent = function (Command: Word; Data: Longint; var CallHelp: Boolean): Boolean of ob ject; property OnHeip: THelpEvent; |
Возникает при каждом обращении к справочной службе
|
property OnHint: TNotifyEvent;
|
Возникает при необходимости отобразить длинную часть оперативной подсказки |
TIdleEvent = procedure (Sender: TObject; var Done: Boolean) of object; property Onldle: TIdleEvent; |
Обработчик этого события реализует фоновую работу (см. ниже пояснения) |
TMessageEvent = procedure (var Msg: TMsg; var Handled: Boolean) of object; property OnMessage: TMessageEvent; |
Возникает при получении программой сообщения Windows. С помощью обработчика этого события можно обработать не сколько или все сообщения до того, как их получит активная форма |
property OnMinimize: TNotifyEvent; |
Возникает при минимизации программы
|
property OnRestore: TNotifyEvent;
|
Возникает при восстановлении программой первоначальных размеров после ее минимизации |
property OnShowHint: TShowHintE- vent; |
Возникает при необходимости отобразить окно с ярлычком оперативной подсказки |
Событие OnIdie возникает всякий раз, когда программа обнаруживает, что ее очередь сообщений пуста. Обработчик этого события может незаметно для пользователя выполнить вспомогательную работу, например, проверить орфографическую правильность только что введенного слова или собрать и обработать статистические данные. Важно помнить, что выполняемая в обработчике работа не может занимать много времени, иначе программа перестанет реагировать на запросы пользователя. Если фоновая работа отнимает много времени, ее следует разбить на сравнительно небольшие фрагменты или периодически вызывать в ней метод HandieMessage. Обработчик в параметре Done сообщает о необходимости продолжить фоновую работу (Done = False) или 0 ее завершении (Done = True). В первом случае программа просмотрит очередь сообщений и после ее очистки вернет управление обработчику OnIdie. Во втором случае программа будет ожидать поступления новых сообщений.
Событие Onidie введено в Delphi 1 для совместимости с Windows З.х в которой не было многопоточности; Если вы работаете с Windows 32 и вам действительно нужно сделать некоторую фоновую работу, имеет смысл поручить ее выполнение отдельному потоку команд(см.га. 14)
Для события ОnShowHint определены такие типы:
type
THintInfo = record
HintControl: TControl;
HintPos: TPoint;
HintMaxWidth: Integer;
HintColor: TColor;
CursorRect: TRect;
CursorPos: TPoint;
ReshowTimeout: Integer;
HideTimeout: Integer;
HintStr: String;
end;
TShowHintEvent =
procedure (var HintStr: String;
var CanShow: Boolean;
var Hintlnfo: THintInfo)
of object;
В параметре HintStr обработчик получает текст, который должен содержать ярлычок, а в параметре Hintlnfo - дополнительную информацию, в том числе: HintControl - элемент, для которого выводится ярлычок; HintPos - координаты верхнего левого угла ярлычка; HintMaxWidth - максимальная ширина окна; HintColor - цвет окна; CursorRect - прямоугольник, в котором должен оставаться указатель мыши, чтобы появился ярлычок; CursorPos - текущее положение указателя мыши; ReshowTimeout - задержка в миллисекундах от момента возникновения события до появления ярлычка;
HideTimeout - время показа ярлычка в миллисекундах.
20.2. SCREEN
Объект screen класса TScrеen инкапсулирует свойства и методы, упрощающие работу с дисплеем ПК, в том числе с его помощью оперативно изменяется вид используемого программой указателя мыши. Как правило, программа устанавливает указатель в виде песочных часов перед началом длинной по времени работы и восстанавливает умалчиваемую форму после ее завершения. Для этого используется свойство Cursor объекта Screen:
Screen.Cursor := crHourGlass;
// Выполняем длительную работу:
….
// Восстанавливаем умалчиваемую срорму:
Screen.Cursor :== crDefault;
Свойства объекта Screen:
property ActiveControl: TWinCon- trol; |
Содержит ссылку на элемент с фокусом ввода |
property ActiveForm: TForm; |
Содержит ссылку на окно с фокусом ввода |
property Cursor: TCursor;
|
Определяет текущий указатель мыши для окон программы |
property Cursors[Index: Integer]: HCursor; |
Открывает доступ к одному из зарегистрированных указателей мыши по его индексу |
property CustomFormCount: Integer;
|
Содержит количество окон или страниц свойств программы, открытых в данный момент |
property CustomForms[Index: Integer] : TCustomForm;
|
Содержит список объектов класса TCustom Form - открытых в данный момент окон программы |
property DataModuleCount: Inte ger; |
Содержит количество модулей данных в программе |
property DataModules[Index: Integer] : TDataModule; |
Содержит список модулей данных - объектов класса TdataModule |
property Fonts: TStrings;
|
Содержит список имен всех экранных шрифтов |
property FormCount: Integer;
|
Содержит общее количество показываемых на экране окон программы |
property Forms[Index: Integer]: TForm; |
Открывает доступ к окну программы по его индексу |
property Height; Integer; |
Содержит высоту экрана в пикселях |
property IconFont: TFont;
|
Определяет шрифт для надписи ниже пиктограммы минимизированной программы |
property PixelsPerInch: Integer;
|
Содержит разрешающую способность экрана в пикселях на линейный дюйм |
property Width: Integer; С объектом screen связаны два |
Содержит ширину экрана в пикселях события: |
property OnActiveControlChange: TNotifyEvent; |
Возникает при переходе фокуса ввода от одного элемента к другому |
property OnActiveFormChange: TNotifyEvent; |
Возникает при переходе фокуса ввода от одной формы к другой |
20.3. PRINTER
Объект Printer автоматически создается, если в программе указана ссылка на модуль printers. Этот объект предоставляет программисту все необходимое для того, чтобы научить программу выводить данные на один из подключенных к ПК принтеров.
Вывод на принтер в Windows ничем не отличается от вывода на экран: в распоряжение программиста предоставляется свойство сап-vas объекта printer, содержащее набор чертежных инструментов и методы, свойственные классу TCanvas. Размер листа бумаги в пикселях принтера определяют свойства Height и Width, а набор принтерных шрифтов - свойство Fonts.
Свойства объекта printer:
property Aborted: Boolean; |
Содержит True, если выполнение предыдущего задания на печать было досрочно прекращено |
property Canvas: TCanvas;
|
Канва принтера - основной инструмент создания изображения на листе бумаги |
type TPrinterCapability = (pcCopies, pcOrientation, pcCollation) ; TPrinterCapabilities = set of TPrinterCapability; property Capabilities: TPrinter Capabilities; |
Содержит возможности текущей настройки драйвера принтера: pcCopies - может печататься несколько копий документа; pcOrien tation -драйвер поддерживает разную ориентацию листа бумаги; pcCollation -документ печатается в подбор по экземплярам |
property Copies: Integer;
|
Указывает требуемое количество копий документа |
property Fonts: TStrings; |
Содержит список всех доступных принтеру шрифтов |
TPrinterOrientation = (poPortrait, poLandscape) ; property Orientation: TPrinterOrientation; |
Определяет ориентацию листа бумаги: poPortrait вертикальная; poLandscape - горизонтальная |
property PageHeight: Integer;
|
Содержит высоту листа бумаги в пикселях принтера |
property PageNumber: Integers;
|
Содержит номер печатаемой страницы документа (начинается с 1) |
property PageWidth: Integer;
|
Содержит ширину листа бумаги в пикселях принтера |
property Printerlndex: Integer; |
Содержит индекс умалчиваемого принтера в списке Printers |
property Printers: TStrings; |
Содержит список всех доступных принтеров |
property Printing: Boolean;
|
Содержит True, если принтер занят печатью документа |
property Title: String; |
Содержит имя задания на печать |
Методы объекта printer: |
|
procedure Abort; |
Досрочно прекращает печать документа |
procedure BeginDoc; |
Начинает печать документа |
procedure EndDoc; |
Завершает печать документа |
procedure NewPage; |
Начинает печать новой страницы документа |
Вот как, например, можно напечатать текст, содержащийся в редакторе Memo 1:
procedure TFormI.ButtonlClick(Sender: TObject);
var
Y,dY,k: Integer;
begin
if Memol.Lines.Count=0 then Exit;
Screen.Cursor := crHourGlass;
with Printer do
begin
BeginDoc;
with Printer.Canvas do
begin
Font := Memol.Font;
dY := TextHeight('1'); // Определяем высоту строки
Y := 2*dY; // Отступ от верхнего края листа
for k := 0 to Memol.Lines.Count-1 do
begin
//Выводим очередную строку TextOut(О,Y,Memol.Lines[k]);
//Смещаемся на следующую строку листа
inc(Y,dY) ;
if PageHeight-Y<2*dY then
// Нижний край листа?
begin //Да
NewPage; //Переход на новый лист
// Выводим номер страницы
TextOut(0,0,'с.'+IntToStr(PageNumber)) ;
Y := 2*dY
end;
end;
end;
EndDoc;
end;
Screen.Cursor := crDefault;
end;
Замечу, что до обращения к BeginDoc программа не имеет никаких сведений о принтере, и поэтому широко распространенной ошибкой будет объединение такого рода:
with Printer, Printer.Canvas do
begin
BeginDoc;
Font.Size := 12;
end;
В этом фрагменте шрифт принтера вряд ли окажется нужного размера, т. к. относится к умалчиваемой канве некоторого абстрактного принтера. Лишь после обращения к BeginDoc канва получит истинные представления о возможностях принтера и сможет правильно управлять его свойствами. Нужно так:
Printer.BeginDoc; //Обращаемся к драйверу принтера
//и настраиваем нужным образом канву
with Printer.Canvas do
begin
Font.Size := 12;
end;
Во многих случаях для печати документа гораздо проще использовать специальные компоненты, расположенные на странице QRe-port галереи компонентов Delphi. Эти компоненты разработаны для создания отчетов по материалам, хранящимся в базах данных, но могут с успехом использоваться и для печати обычных документов. Центральный компонент QuickRep имеет метод preview, с помощью которого можно просмотреть образ печатного документа и при желании напечатать документ.
Методику использования компонентов QReport поясню на следующем примере. Пусть на форме Form1 имеется текстовый редактор Memol, просмотр содержимого которого в виде образа печатного документа открывает нажатие кнопки Button1. Создайте в проекте новую пустую форму Form2 и положите на нее компонент QuickRepl.
На этот компонент положите QRBand1, а на него - QRMemo1. Напишите такой обработчик нажатия кнопки Buttoni:
procedure TFormI.ButtonlClick(Sender: TObject);
begin
with Form2 do
begin
//Копируем содержимое Memol в QRMemo1:
QRMemoi.Lines.Assign(Memol.Lines);
//Используем установленный в Memol шрифт:
QRMemoi.Font := Memol.Font;
//Вызываем окно просмотра и печати документа:
QuickRepl.Preview
end;
end;
Окно просмотра образа печатного документа, появляющееся после щелчка по кнопке Buttoni, показано на рис. 20.1. Инструментальная кнопка В позволяет напечатать документ, а кнопка В - выбрать нужный принтер и настроить его параметры. При печати будут автоматически формироваться страницы документа, при необходимости они могут снабжаться заголовками, нумероваться и т. д.
Рис. 20.1. Окно просмотра печатного документа
20.4. CLIPBOARD
В Windows широко используется буфер межпрограммного обмена данными Clipboard. Если программа Delphi сослалась на модуль Сlipbrd, для нее становится доступным автоматически созданный объект clipboard, инкапсулирующий методы и свойства для работы с буфером.
Свойства объекта clipboard:
property AsTex-t: Strings; |
Рассматривает содержимое буфера как текстовую строку длиной до 255 символов. Для обмена с буфером более длинными строками следует использовать его методы SetTextBuf и GetTextBuf |
property FormatCount: Integers; |
Возвращает общее количество форматов хранящихся в буфере данных |
property Formats[Index: Integer]: Word; |
Открывает доступ к данным по формату, указанному индексом Index |
Методы объекта clipboard: |
|
procedure Assign(Source: TPersistent) ; |
Копирут в буфер изображение |
procedure Clear; procedure Closes; |
Очищает буфер Уменьшает на 1 счетчик блокировок буфера и закрывает его, если счетчик содержит 0 |
function GetTextBuf(Buffer: PChar; BufSize: Integer): Integers; |
Копирует из clipboard не более BufSize символов в текстовый буфер Buffer и возвращает действительное количество скопированных символов |
procedure HasFormat(Format: Word): Boolean; procedure Open; |
Возвращает True, если буфер содержит данные в формате Format Увеличивает на 1 счетчик блокировок буфера и открывает его, если он еще не был открыт |
procedure SetTextBuf(Buffer: PChar); |
Помещает в clipboard содержимое текстового буфера Buffer |
Чтобы поместить в буфер изображение, хранящееся, например, в объекте BitMap класса TBitMap, следует обратиться к методу Assign буфера:
Clipboard.Assign(BitMap);
а для копирования изображения из буфера - к методу Assign объекта-приемника: BitMap.Assign(Clipboard) ;
20.5. НАСТРОЙКА ПРОГРАММ
Удобным средством хранения индивидуальных параметров настройки программы являются широко используемые в Windows З.х файлы инициации (файлы с расширением ini). Для Windows 32 индивидуальная настройка программ реализуется с помощью системного реестра. В этом разделе рассматриваются оба способа, т. к. даже если вы работаете с Windows 32, перенос программ на другие ПК проще реализовать с помощью ini-файлов.
20.5.1. Файлы инициации
Файлы инициации в Delphi связаны с объектами класса TIniFile. Эти объекты не являются глобальными и создаются программно по мере надобности. С каждой программой можно связать сколько угодно файлов инициации.
Физически файл инициации представляет собой обычный текстовый файл, который сохраняется либо в каталоге запуска программы (локальный файл), либо в каталоге запуска Windows (глобальный файл инициации). Файл содержит ряд секций, каждая из которых имеет заголовок и следующие за ним параметры. Заголовок - это произвольный английский текст, заключенный в квадратные скобки. Каждый параметр представлен строкой вида
<ИМЯ_ПАРАМЕТРА>=<ЗНАЧЕНИЕ>
Например:
[Location]
DataBase=C:\mybase Graphics=C:\BITMAP
В этом примере в секции Location файла инициации представлены два параметра с именами DataBase и Graphics. Объекты класса TiniFiie предоставляют удобные средства чтения/записи параметров по именам параметров и секций.
В объекте имеется единственное свойство Filename: String, содержащее имя файла инициации с возможным маршрутом поиска.
Методы класса TIniFile:
constructor Create(const FileNameString) ; |
Создает объект-файл с именем FileName. Это имя автоматически переносится в свойство FileName. Если физический файл существовал, он открывается, если нет создается |
procedure DeleteKey(const Section, Ident: String) ; |
Уничтожает значение параметра Ident в секции Section. Если указана несуществующая секция или имя несуществующего параметра, метод создаст секцию и/или установит в ней параметр с пустым значением |
procedure EraseSection(const Section: String) ;
|
Удаляет секцию со всеми ее параметрами. Если секции не существует, возникает исключительная ситуация |
function ReadBool (const Section, Ident:.String; Default: Boolean): Boolean; |
Возвращает значение логического параметра Ident в секции section. Возвращает Default, если не существует указанная секция, или в ней нет нужного параметра, или, наконец, параметр имеет не логическое значение |
function Readlnteger(const Section, Ident: String; Default:Longint): Longint;
|
Возвращает значение целого параметра Ident в секции Section, Возвращает Default, если не существует указанная секция, или в ней нет нужного параметра, или, наконец, параметр имеет не целое значение |
procedure ReadSection (const Section: String; Strings: TStrings); |
Помещает в список Strings имена всех параметров из секции Section |
procedure ReadSections (Strings: TStrings); |
Помещает в список Strings имена всех секций файла |
procedure ReadSectionValues(const Section: String; Strings: TStrings) ; |
Помещает в список strings имена всех значений из секции Section |
function ReadString(const Section, Ident, Default: String): String;
|
Возвращает значение строкового параметра Ident в секции section. Возвращает Default, если не существует указанная секция, или в ней нет нужного параметра, или, наконец, параметр не имеет значения |
procedure WriteBool(const Section, Ident: String; Value: Boolean); |
Записывает в параметр Ident секции section логическое значение value. |
procedure Writelnteger(const Sec tion, Ident: String; Value: Longint) ; |
Записывает в параметр Ident секции Section целое значение Value |
procedure WriteString(const Section, Ident, Value: String); |
Записывает в параметр Ident секции Section строковое значение value |
20.5.2. Системный реестр Windows
Системный реестр Windows - это общедоступная база данных, хранящая индивидуальную для каждого компьютера настроечную информацию, используемую программным обеспечением. Данные в реестре упорядочены в древовидные структуры, состоящие из узлов, которые в терминологии Windows называются ключами. Каждый ключ имеет один родительский ключ, один или несколько дочерних ключей и ноль или несколько параметров типа <имя_парамет-ра>=<значение>, Исключение представляют, корневые ключи (они не имеют родителей) и дочерние ключи низшего уровня (они не имеют дочерних ключей). По умолчанию несистемное программное обеспечение регистрирует свою информацию в корневом ключе с именем hkey_current_user. Для просмотра/коррекции системного реестра используется системная утилита regedit.exe. Системному реестру Windows соответствует объект класса TRegistry.
Методы класса TRegistry:
procedure CioseKey; |
Записывает информацию в ключ и закрывает его |
constructor Create;
|
Создает объект класса TRegistry. Устанавливает в RootKey значение hkeycurrent - user и в LazyWrite значение True |
function CreateKey(const Key: String): Boolean;
|
Создает ключ с именем Key. Если имя начинается символом “\”, ключ является подключом корневого ключа, в противном случае - подключом текущего ключа |
function DeleteKey(const Key: String): Boolean; |
Удаляет ключ Key и возвращает True, если операция прошла успешно |
function DeleteValue(const Name: String): Boolean; |
В текущем узле удаляет значение параметра с именем Name |
destructor Destroy; |
Уничтожает объект TRegistry |
TRegDataType == (rdUnknown, rdString, rdExpandString, rdlnteger, rdBinary) ; TRegDataInfo = record RegData: TRegDataType; DataSize: Integers- end; |
Возвращает в параметре value значение, определяющее тип данных для параметра сименем valueName текущего ключа: rdunknown - неизвестный тип; rdString - стро ковый тип;rdExpandString - значением является строка, описывающая переменную окружения Windows, например “%РАТН%”; |
function GetDataInfo(const ValueName: String; var Value: TRegDataInfo) : Boolean; |
rdlnteger - целочисленный тип; rdBinary - двоичный тип (набор битов) |
function GetDataSize(const Valu- eName: String): Integer; |
Возвращает длину значения параметра с именем valueName в текущем узле |
TRegDataType = (rdUnknown, rdString, rdExpandString, rdlnteger, rdBinary) ; function GetDataType(const ValueName: String): TRegDataType; |
Возвращает значение, определяющее тип данных для параметра с именем ValueMame текущего ключа (см. метод GetDataInfo) |
TRegKeyInfo = record NumSubKeys: Integer; MaxSubKeyLen: Integer; NumValues: Integer; MaxValueLen: Integer; MaxDataLen: Integer; FileTime: TFileTime; end; function GetKeyInfo(var Value: TRegKeyInfo): Boolean; |
Возвращает в параметре Value информацию о текущем узле: - NumSubKeys количество дочерних узлов;MaxSubKeyLen - максимальная длина имени дочернего узла; NumValues - количество параметров; Мах-valueben - максимальная длина имени параметра; MaxDataLen - максимальна длина параметра; FileTime - время последнего обновления ключа |
procedure GetKeyNames(Strings:TStrings) ; |
Возвращает в параметре strings имена всех дочерних ключей |
procedure GetValueNames(Strings:TStrings) ; |
Возвращает в параметре Strings имена всех параметров |
function HasSubKeys: Boolean;
|
Возвращает True, если ключ имеет дочерние ключи |
function KeyExists(const Key: String): Boolean; |
Возвращает True, если существует ключ с именем Key |
function LoadKey(const Key, File- Name: String): Boolean; |
Создает ключ с именем Key как дочерний ключ корневого ключа и загружает из файла FileName его содержимое (параметры и все подключи) |
procedure MoveKey(const OldName, NewName: String; Delete: Boolean) ; |
Копирует или перемещает ключ OldName в ключ NewName: Delete -содержит True для перемещения |
function OpenKey(const Key: String; CanCreate: Boolean): Boolean;
|
Открывает существующий или создает и открывает новый ключ с именем Key и воз вращает True, если операция прошла успешно. CanCreate разрешает/запрещает создание ключа, если он не существует |
function ReadBinaryData(const Name: String; var Buffer; BufSize: Integer): Integer;
|
Копирует не более Bufsize байт в переменную Buffer из параметра с именем Name. Возвращает количество действительно скопированных байтов |
function ReadXXXX(const Name: String): YYYY; |
Возвращает значение параметра типа yyyy с именем Name |
function RegistryConnect(const UNCName: String): Boolean-
|
Разрешает удаленному компьютеру ONCName доступ к системному реестру вашего компьютера |
procedure RenameValue(const Old Name, NewName: Strings; |
Переименовывает параметр OldName |
function ReplaceKey(const Key FileName, BackUpFileName: String): Boolean; |
Заменяет содержимое ключа Key содержимым файла FileName.BackUpFileName -имя файла, в котором будет сохраняться старое содержимое ключа |
function RestoreKey(const Key, FileName: String): Boolean; |
Считывает содержимое ключа Key из файла FileName |
function SaveKey(const Key, File Name: String): Boolean; |
Сохраняет содержимое ключа Key в файле FileName |
function ValueExists(const Name: String): Boolean; |
Возвращает True, если параметр с именем Name имеет значение |
procedure WriteBinaryData(const Name: String; var Buffer; Buf- Size: Integer) ; |
Копирует не более Bufsize байтов из буфера Buffer в параметр с именем Name
|
procedure WriteXXXX(const Name: String; Value: YYYY); |
Записывает в параметр с именем Name данные Типа YYYY |
Delphi создает надстройку над классом TRegistry для того, чтобы манипуляция с системным реестром Windows была подобна манипуляциям с файлами инициации. Эта надстройка инкапсулируется в классе TRegIniFile.
Класс TRegIniFile имеет свойство FileName: String, Хранящее имя ключа, для которого будут осуществляться нужные действия. Эти действия реализуются следующими методами класса:
constructor Create(const FileName : String) ; |
Создает объект класса TRegIniFile и связывает его с ключом FileName |
procedure DeleteKey(const Section, Ident: String); |
Удаляет параметр с именем Ident в ключе Section |
procedure EraseSection(const Section : String) ; |
Удаляет ключ section со всеми его параметрами и под ключами |
function ReadBool(const Section, Ident: String; Default: Boolean): Boolean; |
Возвращает значение логического параметра с именем Ident в ключе section
|
function Readlnteger(const Sec tion, Ident: String; Default: Longint): Longint; |
Возвращает значение целочисленного параметра с именем Ident в ключе Section
|
procedure ReadSection(const Section: String; Strings: TString); |
Возвращает в Strings имена всех параметров ключа Section |
procedure ReadSections(Strings:TStrings); |
Возвращает в Strings имена всех ключей, связанных с текущим ключом |
procedure ReadSectionValues(const Section: String; Strings: TStrings) ; |
Возвращает в Strings значения всех пара метров ключа section |
function ReadString(const Sec tion, Ident, Default: String):String; |
Возвращает значение строкового параметра с именем Ident в ключе section |
procedure WriteBool(const Sec tion, Ident: String; Value: Boolean) ; |
Записывает логическое значение value в параметр Ident ключа section |
procedure Writelnteger(const Sec tion, Ident: String; Value: Longint) ; |
Записывает целочисленное значение Value в параметр Ident ключа Section |
procedure WriteString(const Sec tion, Ident, Value: String); |
Записывает строковое значение value в параметр Ident ключа Section |